/*
 *  texture.h
 *  BioBreak
 *
 *  Created by terry franguiadakis on 2/27/09.
 *  Copyright 2009 __MyCompanyName__. All rights reserved.
 *
 */
#pragma once

#include "singleton.h"
#include <vector>
#include <string>
#include "subsystem.h"
#include "bbmath.h"

#import "importutils.h"

// -----------------------------------------------------------------------------
class CTexture;
class CTextureAtlas;
class CLabel;
class CTextureCounter;
// -----------------------------------------------------------------------------

class CTextureMgr : public TSingleton<CTextureMgr>, public CSubsystem
{
	typedef CSubsystem super;

public:   
	CTextureMgr();
    ~CTextureMgr();
	
	void                    OnInit();
    const CTexture*         CreateTexture(const char* i_filename);
    const CTextureAtlas*    CreateTextureAtlas(const char* i_filename, unsigned int i_xstep, unsigned int i_ystep);
    CTextureCounter*        CreateTextureCounter();
    
    CLabel*                 CreateLabel(const char* i_text, const char* i_font, int i_fontSize);
    
    const CTexture*	GetLoadedTexture(const char* i_fileName);
    void            EnableTextures(bool i_enabled);
	const CTexture*	GetMissingTexture() {
						return m_missingTexture; }
    
private:

	const CTexture*				m_missingTexture;
    const CTextureAtlas*        m_missingTextureAtlas;
    CTextureCounter*            m_textureCounter;
    
    std::vector<CTexture*>		m_textures;
	std::vector<std::string>	m_textureFileNames;
};

inline CTextureMgr& CTextureMgr_GetSingleton() { return CTextureMgr::GetSingleton(); }
#define g_texturemgr (CTextureMgr_GetSingleton())

// -----------------------------------------------------------------------------

class CTexture 
{
    private:
        friend class CTextureMgr;
        
        void SetTexID(unsigned int i_texid) {
            m_texId = i_texid;
        }
        void SetSizes(unsigned int i_width, unsigned int i_height) {
            m_width = i_width ; m_height = i_height;
        }
        
    void Delete();
    public:

        
        virtual void Apply() const;
        
        unsigned int GetWidth() const {
            return m_width;
        }
        unsigned int GetHeight() const {
            return m_height;
        }
        
    protected:

        
        unsigned int m_texId;
        unsigned int m_width; // in pixels.
        unsigned int m_height;
};

// -----------------------------------------------------------------------------

class CTextureAtlas : public CTexture
{
    friend class CTextureMgr;
public:
    void Init(unsigned int i_texId, unsigned int i_width, unsigned int i_height, const Vector2f& i_maxST, float i_xstep, float i_ystep)
    {
        m_texId = i_texId;
        m_maxS = i_maxST.x ; m_maxT = i_maxST.y;
        m_width = i_width; m_height = i_height;
        m_xStep = i_xstep; m_yStep = i_ystep;
    }
    
    void Draw(const Vector2f& i_pos, const Vector2f& i_size, const Color4f& i_color, unsigned int i_frameNumber) const ;
    void Draw(const Color4f& i_color, unsigned int i_frameNumber) const 
    {
        Draw(Vector2f(0,0), Vector2f(1,1), i_color, i_frameNumber);
    }

    virtual ~CTextureAtlas();
private:
    void setup();
    
    float m_xStep, m_yStep;
    float m_maxS, m_maxT;
    
    std::vector<Vector2f> m_quads;
};

// -----------------------------------------------------------------------------
// Texture Counter 
// Displays dynamic numbers 
// valid string ./012345679
// Draws only in screen space.
// -----------------------------------------------------------------------------
class CTextureCounter : public CTextureAtlas
{
public:
    void SetString(const std::string& i_string) {
        m_stringdata = i_string;
    }
    void SetInterval(float i_xinterval, float i_yinterval) {
        m_xinterval = i_xinterval ; m_yinterval = i_yinterval;
    }
    void Draw(const Vector2f& i_pos, const Color4f& i_color) const;
private:
    std::string m_stringdata;
    float m_xinterval;
    float m_yinterval;
};

// -----------------------------------------------------------------------------
// a label class
// Labels can only be drawn in window space.
// -----------------------------------------------------------------------------
class CLabel : public CTexture 
{
    friend class CTextureMgr;
    
public:
    
    void Init(unsigned int i_texId, unsigned int i_width, unsigned int i_height, const Vector2f& i_maxST, float i_fontSize)
    {
        m_texId = i_texId;
        m_maxS = i_maxST.x ; m_maxT = i_maxST.y;
        m_width = i_width; m_height = i_height;
        m_fontSize = i_fontSize;
    }
    
    void Draw(const Vector2f& i_pos, const Color4f& i_color);
    
 private:
    
    virtual void Apply() const 
    {
        CTexture::Apply();
    }; 
    
    float m_maxS, m_maxT;
    float m_xStep, m_yStep;
    float m_charRatio;
    float m_fontSize;
 };


// -- eof
